<?php
/**
 * Rsa.php
 *
 * @author: cnx7 <zysafe@live.cn> 2020-04-02
 */

namespace common\domain\helper;

class Rsa
{

    /**
     * RSA签名
     * @param $data array 待签名数据
     * @param $private_key string 私钥字符串
     * return 签名结果
     * @return string
     */
    public static function rsaSign($data, $private_key, $sign_type = OPENSSL_ALGO_SHA1)
    {
        ksort($data);
        $params_str = "";
        foreach ($data as $key => $val) {
            if (
                $key != "sign" &&
                $key != "sign_type" &&
                $key != "sign_version" &&
                isset ($val) &&
                @$val != ""
            ) {
                $params_str .= $key . "=" . $val . "&";
            }
        }
        $params_str = substr($params_str, 0, -1);
        $params_str = mb_convert_encoding($params_str, 'UTF-8');

        $data = $params_str;

        $search = [
            "-----BEGIN RSA PRIVATE KEY-----",
            "-----END RSA PRIVATE KEY-----",
            "\n",
            "\r",
            "\r\n"
        ];

        $private_key = str_replace($search, "", $private_key);
        $private_key = $search[0] . PHP_EOL . wordwrap($private_key, 64, "\n", true) . PHP_EOL . $search[1];
        $res = openssl_get_privatekey($private_key);

        if ($res) {
            openssl_sign($data, $sign, $res, $sign_type);
            openssl_free_key($res);
        } else {
            exit("私钥格式有误");
        }

        $sign = base64_encode($sign);
        return $sign;
    }

    /**
     * RSA验签
     * @param $data array 待签名数据
     * @param $public_key string 公钥字符串
     * @param $sign string 要校对的的签名结果
     * return 验证结果
     * @return bool
     */
    public static function rsaCheck($data, $public_key, $sign, $sign_type = OPENSSL_ALGO_SHA1)
    {
        ksort($data);
        $params_str = "";
        foreach ($data as $key => $val) {
            if (
                $key != "sign" &&
                $key != "sign_type" &&
                $key != "sign_version" &&
                isset ($val) &&
                @$val != ""
            ) {
                $params_str .= $key . "=" . $val . "&";
            }
        }
        $params_str = substr($params_str, 0, -1);
        $params_str = mb_convert_encoding($params_str, 'UTF-8');

        $data = $params_str;

        $search = [
            "-----BEGIN PUBLIC KEY-----",
            "-----END PUBLIC KEY-----",
            "\n",
            "\r",
            "\r\n"
        ];
        $public_key = str_replace($search, "", $public_key);
        $public_key = $search[0] . PHP_EOL . wordwrap($public_key, 64, "\n", true) . PHP_EOL . $search[1];
        $res = openssl_get_publickey($public_key);
        if ($res) {
            $result = (bool)openssl_verify($data, base64_decode($sign), $res);
            openssl_free_key($res);
        } else {
            exit("公钥格式有误!");
        }
        return $result;
    }

}
